/* Copyright 2024 zozo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Author: zozo
// Date: 2024-06-02

// Description: Test program for the Data Ring Protection (DRP) module.
// This test creates an instance of the DRP module and performs a series of
// operations to validate the functionality of the module. It stores three
// distinct strings into the module and then retrieves them to ensure that
// the storage and consumption mechanisms work as expected.

#include <stdio.h>
// #include <stdlib.h>
#include <string.h>

#include "drp.h"

DataRingProtection *drp;
// 存储数据的指针变量
// uint8_t *storedPointer1, *storedPointer2, *storedPointer3;

size_t variable = 42;

char *test_srcStrings[3] = {"Hello World", "Data Ring", "Test String"};

void test_pointer(uint8_t index, uint8_t **pointer)
{
    // 让 pointer 指向  test_srcStrings  index 对应的  成员地址
    *pointer = (uint8_t *)&test_srcStrings[index];

    // 打印 地址
    printf("The address is index =0x%x var=0x%x\n", (uint8_t *)&test_srcStrings[index]);
    // 打印指针指向的地址
    printf("The address is point=0x%x var=0x%x\n", *pointer);
}

int drp_test()
{
    // 定义数据环形保护的容量和单个数据块的大小
    const size_t capacity = 4;
    const size_t dataLength = 16; // 假设每个字符串的最大长度为15个字符加上终止符'\0'

    // 测试 指针打印
    // size_t variable1 = 42;
    uint8_t *pointer = NULL;
    printf("The address is point=0x%x\n", pointer);

    test_pointer(1, &pointer);

    // 打印指针指向的地址
    printf("The address is point=0x%x\n", pointer);
    printf("The address is null: %d\n", pointer == NULL ? 1 : 0);

    // 创建DataRingProtection实例
    drp = DataRingProtection_Create(capacity, dataLength);
    if (drp == NULL)
    {
        printf("Failed to create DataRingProtection instance.\n");
        return 1;
    }

    // Consumed Data 1times  测试
    // 创建4个源数据数组并放入不同的字符串 其中第4个字符串 长度要等于32
    const char *srcStrings[4] = {"Hello World", "Data Ring", "Test String",
                                 "Test Long String: is very very very long"};

    // 创建三个数组用于接收存储的数据
    uint8_t *storedPointer1, *storedPointer2, *storedPointer3, *storedPointer4;

    // 存储数据
    if (!DataRingProtection_StoreData(drp, (const uint8_t *)srcStrings[0], strlen(srcStrings[0]), &storedPointer1) ||
        !DataRingProtection_StoreData(drp, (const uint8_t *)srcStrings[1], strlen(srcStrings[1]), &storedPointer2) ||
        !DataRingProtection_StoreData(drp, (const uint8_t *)srcStrings[2], strlen(srcStrings[2]), &storedPointer3) ||
        !DataRingProtection_StoreData(drp, (const uint8_t *)srcStrings[3], strlen(srcStrings[3]), &storedPointer4))
    {
        printf("Failed to store one or more data items.\n");
        DataRingProtection_Destroy(drp);
        return 1;
    }
    else
    {
        printf("Stored Data Success\n");
        // 打印四个返回的数据指针指向的地址
        printf("Stored Data Pointer storedPointer1=0x%x storedPointer2=0x%x storedPointer3=0x%x storedPointer4=0x%x\n",
               storedPointer1, storedPointer2, storedPointer3, storedPointer4);
        // 打印 storedPointer1 是否为空
        printf("Stored Data Pointer1 is null: %d\n", storedPointer1 == NULL ? 1 : 0);
        // 打印 storedPointer2 是否为空
        printf("Stored Data Pointer2 is null: %d\n", storedPointer2 == NULL ? 1 : 0);
        // 打印 storedPointer3 是否为空
        printf("Stored Data Pointer3 is null: %d\n", storedPointer3 == NULL ? 1 : 0);
        // 打印 storedPointer4 是否为空
        printf("Stored Data Pointer4 is null: %d\n", storedPointer4 == NULL ? 1 : 0);
    }

    // 消费数据
    // 创建四个数组用于接收消费的数据
    uint8_t consumedData1[dataLength], consumedData2[dataLength], consumedData3[dataLength], consumedData4[dataLength];
    size_t datalength1, datalength2, datalength3, datalength4;

    // 假设 storedPointer4 也已经被赋值指向有效的数据
    if (!DataRingProtection_ConsumeData(drp, storedPointer1, consumedData1, &datalength1) ||
        !DataRingProtection_ConsumeData(drp, storedPointer2, consumedData2, &datalength2) ||
        !DataRingProtection_ConsumeData(drp, storedPointer3, consumedData3, &datalength3) ||
        !DataRingProtection_ConsumeData(drp, storedPointer4, consumedData4, &datalength4))
    {
        printf("Failed to consume one or more data items.\n");
        DataRingProtection_Destroy(drp);
        return 1;
    }
    else
    {
        printf("==========Consumed Data Success 1times ==============\n");
        // 打印 consumedData1 至 consumedData4
        printf("Consumed Data consumedData1=%s\n", consumedData1);
        printf("Consumed Data consumedData2=%s\n", consumedData2);
        printf("Consumed Data consumedData3=%s\n", consumedData3);
        printf("Consumed Data consumedData4=%s\n", consumedData4); // 打印第四个数据数组的内容

        // 打印 datalength1 至 datalength4
        printf("Consumed Data Length datalength1=%d datalength2=%d datalength3=%d datalength4=%d\n",
                datalength1, datalength2, datalength3, datalength4);
    }

    const char *next_test[4] = {"Test2 Long String in index0: is very very very long", "B", "C", "D"};
// 存储数据
    if (!DataRingProtection_StoreData(drp, (const uint8_t *)next_test[0], strlen(next_test[0]), &storedPointer1) ||
        !DataRingProtection_StoreData(drp, (const uint8_t *)next_test[1], strlen(next_test[1]), &storedPointer2) ||
        !DataRingProtection_StoreData(drp, (const uint8_t *)next_test[2], strlen(next_test[2]), &storedPointer3) ||
        !DataRingProtection_StoreData(drp, (const uint8_t *)next_test[3], strlen(next_test[3]), &storedPointer4))
    {
        printf("Failed to store one or more data items.\n");
        DataRingProtection_Destroy(drp);
        return 1;
    }
    else
    {
        printf("Stored Data Success\n");
        // 打印四个返回的数据指针指向的地址
        printf("Stored Data Pointer storedPointer1=0x%x storedPointer2=0x%x storedPointer3=0x%x storedPointer4=0x%x\n",
               storedPointer1, storedPointer2, storedPointer3, storedPointer4);
        // 打印 storedPointer1 是否为空
        printf("Stored Data Pointer1 is null: %d\n", storedPointer1 == NULL ? 1 : 0);
        // 打印 storedPointer2 是否为空
        printf("Stored Data Pointer2 is null: %d\n", storedPointer2 == NULL ? 1 : 0);
        // 打印 storedPointer3 是否为空
        printf("Stored Data Pointer3 is null: %d\n", storedPointer3 == NULL ? 1 : 0);
        // 打印 storedPointer4 是否为空
        printf("Stored Data Pointer4 is null: %d\n", storedPointer4 == NULL ? 1 : 0);
    }

    // Consumed Data 1times  测试
    // 假设 storedPointer4 也已经被赋值指向有效的数据
    // 清除 consumedData
    memset(consumedData1, 0, dataLength);
    memset(consumedData2, 0, dataLength);
    memset(consumedData3, 0, dataLength);
    memset(consumedData4, 0, dataLength);
    if (!DataRingProtection_ConsumeData(drp, storedPointer1, consumedData1, &datalength1) ||
        !DataRingProtection_ConsumeData(drp, storedPointer2, consumedData2, &datalength2) ||
        !DataRingProtection_ConsumeData(drp, storedPointer3, consumedData3, &datalength3) ||
        !DataRingProtection_ConsumeData(drp, storedPointer4, consumedData4, &datalength4))
    {
        printf("Failed to consume one or more data items.\n");
        DataRingProtection_Destroy(drp);
        return 1;
    }
    else
    {
        printf("==========Consumed Data Success 2 times ==============\n");
        // 打印 consumedData1 至 consumedData4
        printf("Consumed Data consumedData1=%s\n", consumedData1);
        printf("Consumed Data consumedData2=%s\n", consumedData2);
        printf("Consumed Data consumedData3=%s\n", consumedData3);
        printf("Consumed Data consumedData4=%s\n", consumedData4); // 打印第四个数据数组的内容

        // 打印 datalength1 至 datalength4
        printf("Consumed Data Length datalength1=%d datalength2=%d datalength3=%d datalength4=%d\n",
                datalength1, datalength2, datalength3, datalength4);
    }

    // Consumed Data 3 times  测试
    typedef struct {
        uint8_t *topic;
        uint8_t *data;
    } DataFormat;

    uint8_t data2[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};

    DataFormat dataFormat[2] ={
        {
            .topic = (uint8_t *)"topic1",
            .data = (uint8_t *)"data1: Hello World!"
        },
        {
            .topic = (uint8_t *)"topic2",
            .data = (uint8_t *)data2
        }
    };

    // 打印 dataFormat 的长度
    printf("dataFormat length=%d\n", sizeof(dataFormat));
    // 打印 dataFormat[0] 的长度
    printf("dataFormat[0] length=%d\n", sizeof(dataFormat[0]));
    // 打印 dataFormat[1] 的长度
    printf("dataFormat[1] length=%d\n", sizeof(dataFormat[1]));

    // 打印 dataFormat[0].topic 的长度 + data 的长度
    printf("dataFormat[0].topic length=%d data length=%d\n", strlen((char *)dataFormat[0].topic), strlen((char *)dataFormat[0].data));
    // 打印 dataFormat[1].topic 的长度 + data 的长度
    printf("dataFormat[1].topic length=%d data length=%d\n", strlen((char *)dataFormat[1].topic), sizeof(data2));

    // 清理资源
    if (!DataRingProtection_Destroy(drp))
    {
        printf("Failed to destroy DataRingProtection instance.\n");
        return 1;
    }

    printf("Test completed successfully.\n");

    return 0;
}